#ifndef	__BFX_XMLNAMESPACEMANAGER_H__
#define	__BFX_XMLNAMESPACEMANAGER_H__

namespace	BFX
{

class REFNameTable;

// Resolves, adds, and removes namespaces to a collection and provides scope management for these namespaces.
class BFX_API REFXMLNamespaceManager : public REFObject
{
public:
	// Initializes a new instance with the specified XmlNameTable.
	REFXMLNamespaceManager(REFNameTable* pNameTable);
	virtual ~REFXMLNamespaceManager();

	// Return the namespace to which the specified prefix is mapped.  Returns null if the prefix isn't mapped to
	// a namespace.  
	// The "xml" prefix is always mapped to the "http://www.w3.org/XML/1998/namespace" namespace.
	// The "xmlns" prefix is always mapped to the "http://www.w3.org/2000/xmlns/" namespace.
	// If the default namespace has not been defined, then the "" prefix is mapped to "" (the empty namespace).
	UniString LookupNamespace(const UniString& strPrefix) const;

	// Return a prefix which is mapped to the specified namespace.  Multiple prefixes can be mapped to the
	// same namespace, and it is undefined which prefix will be returned.  Returns null if no prefixes are
	// mapped to the namespace.  
	// The "xml" prefix is always mapped to the "http://www.w3.org/XML/1998/namespace" namespace.
	// The "xmlns" prefix is always mapped to the "http://www.w3.org/2000/xmlns/" namespace.
	// If the default namespace has not been defined, then the "" prefix is mapped to "" (the empty namespace).
	UniString LookupPrefix(const UniString& strNamespaceName) const;

	// Gets a value indicating whether the supplied prefix has a namespace defined for the current pushed scope.
	// Returns true if there is a namespace defined; otherwise, false.
	bool HasNamespace(const UniString& strPrefix) const;
	// Adds the given namespace to the collection.
	bool AddNamespace(const UniString& strPrefix, const UniString& strUri);
	// Removes the given namespace for the given prefix.
	void RemoveNamespace(const UniString& strPrefix, const UniString& strUri);

	// Pushes a namespace scope onto the stack.
	void PushScope();
	// Pops a namespace scope off the stack.
	// Returns true if there are namespace scopes left on the stack; false if there are no more namespaces to pop.
	bool PopScope();

private:
	int LookupNamespaceDecl(const UniString& strPrefix) const;

private:
	// Namespace declaration
	struct NamespaceDeclaration
	{
		UniString	m_strPrefix;
		UniString	m_strUri;
		int			m_nScopeId;
		int			m_nPreviousNsIndex;
		// helpers
		void Set(const UniString& strPrefix, const UniString& strUri, int nScopeId, int nPreviousNsIndex);
	};

private:
	// array with namespace declarations
	NamespaceDeclaration*	m_pNsDecls;
	int		m_nNsDeclsLength;

	// index of last declaration
	int		m_nLastDecl;

	// name table
	REFNameTable*	m_pNameTable;
	// ID (depth) of the current scope
	int		m_nScopeId;

	// atomized prefixes for "xml" and "xmlns"
	UniString	m_strXml;
	UniString	m_strXmlNs;
};

}	//	namespace	BFX

#endif	//	__BFX_XMLNAMESPACEMANAGER_H__
